const unique = require("./template.js")

function testUnique() {
  console.log("=== 数组去重测试 ===")

  console.log(
    "1. 基本数字去重:",
    (() => {
      const arr = [1, 2, 2, 3, 3, 3, 4]
      const result = unique(arr)
      return JSON.stringify(result) === JSON.stringify([1, 2, 3, 4])
    })()
  )

  console.log(
    "2. 字符串去重:",
    (() => {
      const arr = ["a", "b", "b", "c", "c", "c", "d"]
      const result = unique(arr)
      return JSON.stringify(result) === JSON.stringify(["a", "b", "c", "d"])
    })()
  )

  console.log(
    "3. 空数组:",
    (() => {
      const arr = []
      const result = unique(arr)
      return JSON.stringify(result) === JSON.stringify([])
    })()
  )

  console.log(
    "4. 单元素数组:",
    (() => {
      const arr = [42]
      const result = unique(arr)
      return JSON.stringify(result) === JSON.stringify([42])
    })()
  )

  console.log(
    "5. 已去重数组:",
    (() => {
      const arr = [1, 2, 3, 4, 5]
      const result = unique(arr)
      return JSON.stringify(result) === JSON.stringify([1, 2, 3, 4, 5])
    })()
  )

  console.log(
    "6. 包含undefined和null:",
    (() => {
      const arr = [1, undefined, 2, null, undefined, 3, null]
      const result = unique(arr)
      return (
        JSON.stringify(result) === JSON.stringify([1, undefined, 2, null, 3])
      )
    })()
  )

  console.log(
    "7. 包含NaN:",
    (() => {
      const arr = [1, NaN, 2, NaN, 3]
      const result = unique(arr)
      return (
        result.length === 4 &&
        result[0] === 1 &&
        Object.is(result[1], NaN) &&
        result[2] === 2 &&
        result[3] === 3
      )
    })()
  )

  console.log(
    "8. 对象数组根据id去重:",
    (() => {
      const arr = [
        { id: 1, name: "Alice" },
        { id: 2, name: "Bob" },
        { id: 1, name: "Alice" },
        { id: 3, name: "Charlie" }
      ]
      const result = unique(arr, (item) => item.id)
      return (
        result.length === 3 &&
        result[0].id === 1 &&
        result[1].id === 2 &&
        result[2].id === 3
      )
    })()
  )

  console.log(
    "9. 对象数组根据name去重:",
    (() => {
      const arr = [
        { id: 1, name: "Alice" },
        { id: 2, name: "Bob" },
        { id: 3, name: "Alice" },
        { id: 4, name: "Bob" }
      ]
      const result = unique(arr, (item) => item.name)
      return (
        result.length === 2 &&
        result[0].name === "Alice" &&
        result[1].name === "Bob"
      )
    })()
  )

  console.log(
    "10. 复杂对象根据嵌套属性去重:",
    (() => {
      const arr = [
        { user: { id: 1 }, role: "admin" },
        { user: { id: 2 }, role: "user" },
        { user: { id: 1 }, role: "moderator" }
      ]
      const result = unique(arr, (item) => item.user.id)
      return (
        result.length === 2 &&
        result[0].user.id === 1 &&
        result[1].user.id === 2
      )
    })()
  )

  console.log(
    "11. 根据计算值去重:",
    (() => {
      const arr = [1, 2, 3, 4, 5, 6]
      const result = unique(arr, (item) => item % 3) // 根据模3的结果去重
      return (
        result.length === 3 &&
        result[0] === 1 &&
        result[1] === 2 &&
        result[2] === 3
      )
    })()
  )

  console.log(
    "12. 混合类型数组:",
    (() => {
      const arr = [1, "1", 2, "2", true, "true"]
      const result = unique(arr)
      return (
        JSON.stringify(result) ===
        JSON.stringify([1, "1", 2, "2", true, "true"])
      )
    })()
  )

  console.log(
    "13. 根据字符串长度去重:",
    (() => {
      const arr = ["a", "bb", "ccc", "a", "bb", "dddd"]
      const result = unique(arr, (item) => item.length)
      return (
        result.length === 4 &&
        result[0] === "a" &&
        result[1] === "bb" &&
        result[2] === "ccc" &&
        result[3] === "dddd"
      )
    })()
  )

  console.log(
    "14. 保持原数组顺序:",
    (() => {
      const arr = [3, 1, 2, 1, 3, 2]
      const result = unique(arr)
      return JSON.stringify(result) === JSON.stringify([3, 1, 2])
    })()
  )

  console.log(
    "15. 对象数组保持顺序:",
    (() => {
      const arr = [
        { id: 3, name: "C" },
        { id: 1, name: "A" },
        { id: 2, name: "B" },
        { id: 1, name: "A" }
      ]
      const result = unique(arr, (item) => item.id)
      return (
        result.length === 3 &&
        result[0].id === 3 &&
        result[1].id === 1 &&
        result[2].id === 2
      )
    })()
  )

  console.log(
    "16. 不修改原数组:",
    (() => {
      const arr = [1, 2, 2, 3]
      const original = [...arr]
      unique(arr)
      return JSON.stringify(arr) === JSON.stringify(original)
    })()
  )

  console.log(
    "17. 返回新数组:",
    (() => {
      const arr = [1, 2, 2, 3]
      const result = unique(arr)
      return result !== arr
    })()
  )

  console.log(
    "18. 包含0和false:",
    (() => {
      const arr = [0, false, 1, true, 0, false]
      const result = unique(arr)
      return JSON.stringify(result) === JSON.stringify([0, false, 1, true])
    })()
  )

  console.log(
    "19. 大数组性能测试:",
    (() => {
      const arr = Array.from({ length: 1000 }, (_, i) => i % 100) // 1000个元素，只有100个唯一值
      const result = unique(arr)
      return result.length === 100
    })()
  )

  console.log(
    "20. this上下文测试:",
    (() => {
      const obj = {
        data: [1, 2, 2, 3, 3, 3, 4],
        getUnique: function() {
          return unique(this.data)
        }
      }
      const result = obj.getUnique()
      return JSON.stringify(result) === JSON.stringify([1, 2, 3, 4])
    })()
  )

  console.log(
    "21. 方法调用this绑定:",
    (() => {
      const obj = {
        prefix: "item_",
        process: function(arr) {
          const uniqueArr = unique(arr)
          return uniqueArr.map(item => this.prefix + item)
        }
      }
      const result = obj.process([1, 2, 2, 3])
      return JSON.stringify(result) === JSON.stringify(["item_1", "item_2", "item_3"])
    })()
  )

  console.log(
    "22. 回调函数this绑定:",
    (() => {
      const obj = {
        key: "id",
        getUniqueByKey: function(arr) {
          return unique(arr, function(item) {
            return item[this.key]
          }.bind(this))
        }
      }
      const data = [
        { id: 1, name: "A" },
        { id: 2, name: "B" },
        { id: 1, name: "C" }
      ]
      const result = obj.getUniqueByKey(data)
      return result.length === 2 && result[0].id === 1 && result[1].id === 2
    })()
  )
}

testUnique()
